home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / dtime / data.1 / Dentry.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-08  |  42.1 KB  |  1,715 lines

  1. /*
  2. Module : DATENTRY.H
  3. Purpose: implementation to a number of classes to allow data entry of the date/time classes
  4. Created: PJN / DATE/1 / 20-02-1996
  5. History: None
  6.  
  7. Copyright (c) 1996 by PJ Naughter.  
  8. All rights reserved.
  9.  
  10. */
  11.  
  12. /////////////////////////////////  Includes  //////////////////////////////////
  13. #include "stdafx.h"
  14. #include "resource.h"
  15. #include "pushpin.h"
  16. #include "win32sup.h"
  17. #include "dentry.h"
  18. #include "dtimeres.h"
  19.  
  20.  
  21.  
  22.  
  23. //////////////////////////////////  Macros  ///////////////////////////////////
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char BASED_CODE THIS_FILE[] = __FILE__;
  27. #define new DEBUG_NEW
  28. #endif
  29.  
  30. #ifndef _WINDOWS
  31. #pragma message("This module should be included in builds for Windows only")
  32. #endif
  33.  
  34.  
  35. ////////////////////////////////// Statics ////////////////////////////////////
  36. #define UWM_DLG_CLOSE  WM_USER + 101
  37. #define MOUSE_MOVE 0xf012
  38.  
  39.  
  40. ////////////////////////////////// Implementation /////////////////////////////
  41. BEGIN_MESSAGE_MAP(CDTDialog, CDialog)
  42.   //{{AFX_MSG_MAP(CDTDialog)
  43.   ON_WM_LBUTTONDOWN()
  44.   ON_WM_ACTIVATE()
  45.   #ifndef _WIN32
  46.   ON_COMMAND(IDC_PUSHPIN, OnPushPin)
  47.   #endif
  48.   //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50.  
  51.  
  52. BEGIN_MESSAGE_MAP(CCDateDlg, CDTDialog)
  53.   //{{AFX_MSG_MAP(CCDateDlg)
  54.   ON_BN_CLICKED(IDC_INVALID, OnInvalid)
  55.   //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57.  
  58.  
  59. BEGIN_MESSAGE_MAP(CCLTimeOfDayDlg, CDTDialog)
  60.   //{{AFX_MSG_MAP(CCLTimeOfDayDlg)
  61.   ON_BN_CLICKED(IDC_INVALID, OnInvalid)
  62.   //}}AFX_MSG_MAP
  63. END_MESSAGE_MAP()
  64.  
  65.  
  66. BEGIN_MESSAGE_MAP(CCLTimeSpanDlg, CDTDialog)
  67.   //{{AFX_MSG_MAP(CCLTimeSpanDlg)
  68.   ON_BN_CLICKED(IDC_INVALID, OnInvalid)
  69.   //}}AFX_MSG_MAP
  70. END_MESSAGE_MAP()
  71.  
  72.  
  73. BEGIN_MESSAGE_MAP(CCLDateDlg, CDTDialog)
  74.   //{{AFX_MSG_MAP(CCLDateDlg)
  75.   ON_BN_CLICKED(IDC_INVALID, OnInvalid)
  76.   //}}AFX_MSG_MAP
  77. END_MESSAGE_MAP()
  78.  
  79.  
  80. BEGIN_MESSAGE_MAP(CDateButton, CButton)
  81.   //{{AFX_MSG_MAP(CDateButton)
  82. #ifdef _WIN32  
  83.   ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
  84. #else                                 
  85.   ON_MESSAGE(UWM_BN_CLICKED, OnMyReflectedClicked)  
  86. #endif  
  87.   ON_MESSAGE(UWM_DLG_CLOSE, OnDlgClose)
  88.   //}}AFX_MSG_MAP
  89. END_MESSAGE_MAP()
  90.  
  91.  
  92. BEGIN_MESSAGE_MAP(CDateTimeControl, CStatic)
  93.   //{{AFX_MSG_MAP(CDateTimeControl)
  94.   //}}AFX_MSG_MAP
  95. END_MESSAGE_MAP()
  96.  
  97.  
  98. BEGIN_MESSAGE_MAP(CDateControl, CDateTimeControl)
  99.   //{{AFX_MSG_MAP(CDateControl)
  100.   ON_MESSAGE(UWM_BN_CLICKED, OnEditClick)
  101.   ON_MESSAGE(UWM_DLG_CLOSE, OnDlgClose)
  102.   //}}AFX_MSG_MAP
  103. END_MESSAGE_MAP()
  104.  
  105.  
  106. BEGIN_MESSAGE_MAP(CLTimeSpanControl, CDateTimeControl)
  107.   //{{AFX_MSG_MAP(CLTimeSpanControl)
  108.   ON_MESSAGE(UWM_BN_CLICKED, OnEditClick)
  109.   ON_MESSAGE(UWM_DLG_CLOSE, OnDlgClose)
  110.   //}}AFX_MSG_MAP
  111. END_MESSAGE_MAP()
  112.  
  113.  
  114. BEGIN_MESSAGE_MAP(CLTimeOfDayControl, CDateTimeControl)
  115.   //{{AFX_MSG_MAP(CLTimeOfDayControl)
  116.   ON_MESSAGE(UWM_BN_CLICKED, OnEditClick)
  117.   ON_MESSAGE(UWM_DLG_CLOSE, OnDlgClose)
  118.   //}}AFX_MSG_MAP
  119. END_MESSAGE_MAP()
  120.  
  121.  
  122. BEGIN_MESSAGE_MAP(CLDateControl, CDateTimeControl)
  123.   //{{AFX_MSG_MAP(CLDateControl)
  124.   ON_MESSAGE(UWM_BN_CLICKED, OnEditClick)
  125.   ON_MESSAGE(UWM_DLG_CLOSE, OnDlgClose)
  126.   //}}AFX_MSG_MAP
  127. END_MESSAGE_MAP()
  128.  
  129.  
  130. CDTDialog::CDTDialog()
  131. {
  132.   m_pParentWnd = NULL;
  133.   m_dwFlags = 0;
  134.   m_bSafeToClose = TRUE;
  135. }
  136.  
  137. CDTDialog::CDTDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd) :
  138.      CDialog(lpszTemplateName, pParentWnd)
  139. {
  140.   m_pParentWnd = pParentWnd;
  141.   m_dwFlags = 0;
  142.   m_bSafeToClose = TRUE;
  143. }
  144.  
  145. CDTDialog::CDTDialog(UINT nIDTemplate, CWnd* pParentWnd) : 
  146.      CDialog(nIDTemplate, pParentWnd)
  147. {
  148.   m_pParentWnd = pParentWnd;
  149.   m_dwFlags = 0;
  150.   m_bSafeToClose = TRUE;
  151. }
  152.  
  153.  
  154. void CDTDialog::OnLButtonDown(UINT /*nFlags*/, CPoint point) 
  155. {
  156.   if (!(m_dwFlags & DT_NODRAG))
  157.   {
  158.     ClientToScreen(&point);
  159.     SendMessage(WM_LBUTTONUP, 0, MAKELONG(point.x, point.y));
  160.     SendMessage(WM_SYSCOMMAND, MOUSE_MOVE, MAKELONG(point.x, point.y));
  161.   }
  162. }
  163.  
  164.  
  165. BOOL CDTDialog::OnInitDialog() 
  166. {
  167.   BOOL rval = CDialog::OnInitDialog();
  168.  
  169.   //adjust the position to concide with the parent button
  170.   ASSERT(m_pParentWnd != NULL);
  171.  
  172.   CRect ParentRect;
  173.   m_pParentWnd->GetWindowRect(ParentRect);
  174.   int y = ParentRect.bottom+3;
  175.   int nMaxY = GetSystemMetrics(SM_CYFULLSCREEN);
  176.   CRect ThisRect;
  177.   GetWindowRect(ThisRect);
  178.   if (y+ThisRect.bottom-ThisRect.top >= nMaxY)
  179.     y = (ParentRect.top - 3 - ThisRect.bottom + ThisRect.top);
  180.   int x = ParentRect.right-ThisRect.right+ThisRect.left;
  181.   if (x < 1)
  182.     x = 1;
  183.   SetWindowPos(NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
  184.  
  185.   //create the push pin button
  186.   if (m_dwFlags & DT_PUSHPIN)
  187.   {                     
  188.     //ensure that bitmaps loads from dtime as 16 bit MFC will
  189.     //not look in extension dlls when loading a bitmap
  190.     #ifndef _WIN32
  191.       #ifdef _DEBUG
  192.         HINSTANCE hDtimeDLL = GetModuleHandle("DT10016D.DLL");
  193.       #else
  194.         HINSTANCE hDtimeDLL = GetModuleHandle("DT10016.DLL");
  195.       #endif
  196.       HINSTANCE hOldResourceHandle = AfxGetResourceHandle();
  197.       AfxSetResourceHandle(hDtimeDLL);
  198.     #endif    
  199.   
  200.     m_btnPushPin.AutoLoad(IDC_PUSHPIN, this);               
  201.                                                           
  202.     #ifndef _WIN32                                                      
  203.       AfxSetResourceHandle(hOldResourceHandle);
  204.     #endif
  205.  
  206.     //add the tooltip for the push pin
  207.     #ifdef _WIN32
  208.       m_TipPushPin.Create(this);
  209.       m_TipPushPin.Activate(TRUE);
  210.       m_TipPushPin.AddTool(GetDlgItem(IDC_PUSHPIN), IDS_TT_PUSHPIN);
  211.     #endif
  212.   }
  213.  
  214.   return rval;
  215. }
  216.  
  217.  
  218. void CDTDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) 
  219. {
  220.   CDialog::OnActivate(nState, pWndOther, bMinimized);
  221.  
  222.   //DT_PUSHPIN & DT_CLOSEONDEACTIVE are mutually exclusive
  223.   if (m_dwFlags & DT_PUSHPIN)
  224.     ASSERT(!(m_dwFlags & DT_CLOSEONDEACTIVE));
  225.   if (m_dwFlags & DT_CLOSEONDEACTIVE)
  226.     ASSERT(!(m_dwFlags & DT_PUSHPIN));
  227.   
  228.   if ((m_dwFlags & DT_MODELESS) && m_bSafeToClose && (nState == WA_INACTIVE))
  229.   {
  230.     if ((m_dwFlags & DT_CLOSEONDEACTIVE) || (m_dwFlags & DT_PUSHPIN && !m_btnPushPin.IsPinned()))
  231.       OnCancel();
  232.   }
  233. }
  234.  
  235.  
  236. BOOL CDTDialog::PreTranslateMessage(MSG* pMsg) 
  237. {
  238.   //give the tooltip a chance to handle the message
  239.   if (m_dwFlags & DT_PUSHPIN)
  240.   {
  241.     #ifdef _WIN32
  242.       m_TipPushPin.RelayEvent(pMsg);
  243.     #endif  
  244.   }
  245.   return CDialog::PreTranslateMessage(pMsg);
  246. }
  247.  
  248.  
  249. void CDTDialog::OnOK()
  250. {
  251.   if (m_dwFlags & DT_MODELESS)
  252.   {
  253.     m_bSafeToClose = FALSE; //to avoid deactivating the window due to a message
  254.                             //that could be displayed during UpdateData
  255.     if (!UpdateData(TRUE))
  256.     {
  257.       TRACE0("UpdateData failed during dialog termination.\n");
  258.       // the UpdateData routine will set focus to correct item
  259.       m_bSafeToClose = TRUE;
  260.       return;
  261.     }
  262.  
  263.     m_bSafeToClose = TRUE;
  264.     m_pParentWnd->PostMessage(UWM_DLG_CLOSE, 1);
  265.     DestroyWindow();
  266.   }  
  267.   else if (m_dwFlags & DT_MODAL)
  268.     CDialog::OnOK();
  269. }
  270.  
  271.  
  272. void CDTDialog::OnCancel()
  273. {
  274.   if (m_dwFlags & DT_MODELESS)
  275.   {
  276.     m_pParentWnd->PostMessage(UWM_DLG_CLOSE, 0);
  277.     DestroyWindow();
  278.   }
  279.   else if (m_dwFlags & DT_MODAL)
  280.     CDialog::OnCancel();
  281. }                                  
  282.  
  283.  
  284. #ifndef _WIN32
  285. void CDTDialog::OnPushPin()
  286. {
  287.   m_btnPushPin.OnClicked();
  288. }             
  289. #endif
  290.  
  291.  
  292. CCDateDlg::CCDateDlg()
  293. {
  294.   m_nDay = 0;
  295.   m_lYear = 0;
  296.   m_bInValid = FALSE;
  297.   m_nDay = 1;
  298.   m_lYear = CDate::CurrentYear();
  299.   m_nMonth = 1;
  300. }
  301.  
  302.  
  303. CCDateDlg::CCDateDlg(CWnd* pParent, DWORD dwFlags)
  304.   : CDTDialog(IDD_CDATE_WITHOUT_PIN, pParent)
  305. {
  306.   //DT_PUSHPIN & DT_CLOSEONDEACTIVE should be used with DT_MODELESS only
  307.   if (dwFlags & DT_PUSHPIN)
  308.     ASSERT(dwFlags & DT_MODELESS);
  309.   if (dwFlags & DT_CLOSEONDEACTIVE)
  310.     ASSERT(dwFlags & DT_MODELESS);
  311.  
  312.   //{{AFX_DATA_INIT(CCDateDlg)
  313.   m_nDay = 0;
  314.   m_lYear = 0;
  315.   m_bInValid = FALSE;
  316.   //}}AFX_DATA_INIT
  317.   m_nDay = 1;
  318.   m_lYear = CDate::CurrentYear();
  319.   m_nMonth = 1;
  320.   m_dwFlags = dwFlags;
  321. }
  322.  
  323.  
  324. BOOL CCDateDlg::Create(CWnd* pParent, DWORD dwFlags)
  325. {
  326.   //should only be created modeless when DT_MODELESS flag is used
  327.   ASSERT(dwFlags & DT_MODELESS);
  328.  
  329.   m_dwFlags = dwFlags;
  330.   m_pParentWnd = pParent;
  331.  
  332.   UINT nIDTemplate = IDD_CDATE_WITHOUT_PIN;
  333.   if (dwFlags & DT_PUSHPIN)
  334.     nIDTemplate = IDD_CDATE;
  335.  
  336.   return CDTDialog::Create(nIDTemplate, pParent);
  337. }
  338.  
  339.  
  340. void CCDateDlg::DoDataExchange(CDataExchange* pDX)
  341. {
  342.   CDTDialog::DoDataExchange(pDX);
  343.   //{{AFX_DATA_MAP(CCDateDlg)
  344.   DDX_Check(pDX, IDC_INVALID, m_bInValid);
  345.   //}}AFX_DATA_MAP
  346.   
  347.   if (!pDX->m_bSaveAndValidate || (pDX->m_bSaveAndValidate && !m_bInValid))
  348.   {
  349.     DDX_Control(pDX, IDC_MONTH, m_ctrlMonth);
  350.     #ifdef _WIN32
  351.       DDX_Control(pDX, IDC_UPDOWN_YEAR, m_ctrlSpinYear);
  352.       DDX_Control(pDX, IDC_UPDOWN_DAY, m_ctrlSpinDay);
  353.     #endif
  354.     DDX_Control(pDX, IDC_INVALID, m_ctrlInvalid);
  355.     DDX_Text(pDX, IDC_YEAR, m_lYear);
  356.     DDX_Text(pDX, IDC_DAY, m_nDay);
  357.   }
  358.  
  359.   if (pDX->m_bSaveAndValidate)
  360.     m_nMonth = m_ctrlMonth.GetCurSel() + 1;
  361.   else
  362.   {
  363.     OnInvalid();
  364.     m_ctrlMonth.SetCurSel(m_nMonth-1);
  365.   }
  366.  
  367.   DDV_MinMaxUInt(pDX, m_nDay, 1, (UINT) CDate::DaysInMonth((WORD) m_nMonth, CDate::IsLeap(m_lYear)));
  368. }
  369.  
  370.  
  371. BOOL CCDateDlg::OnInitDialog() 
  372. {
  373.   //Add the month strings
  374.   CComboBox* pMonthCombo = (CComboBox*) GetDlgItem(IDC_MONTH);
  375.   for (WORD i=1; i<13; i++)
  376.     pMonthCombo->AddString(CDate::GetFullStringMonth(i));
  377.  
  378.   //Call up to the parent
  379.   BOOL rval = CDTDialog::OnInitDialog();
  380.  
  381.   #ifdef _WIN32
  382.     m_ctrlSpinYear.SetRange(UD_MINVAL, UD_MAXVAL);
  383.     m_ctrlSpinDay.SetRange(1, 31);
  384.   #endif
  385.  
  386.   //disable the invalid check box if required
  387.   if (m_dwFlags & DT_ONLYVALID)
  388.     m_ctrlInvalid.EnableWindow(FALSE);
  389.  
  390.   return rval;
  391. }
  392.  
  393.  
  394. void CCDateDlg::OnInvalid() 
  395. {
  396.   BOOL bEnable = !m_ctrlInvalid.GetCheck();
  397.   GetDlgItem(IDC_DAY_PRMPT)->EnableWindow(bEnable);
  398.   GetDlgItem(IDC_MONTH_PRMPT)->EnableWindow(bEnable);
  399.   GetDlgItem(IDC_YEAR_PRMPT)->EnableWindow(bEnable);
  400.   GetDlgItem(IDC_DAY)->EnableWindow(bEnable);
  401.   GetDlgItem(IDC_MONTH)->EnableWindow(bEnable);
  402.   GetDlgItem(IDC_YEAR)->EnableWindow(bEnable);
  403.   m_ctrlMonth.EnableWindow(bEnable);
  404.   #ifdef _WIN32
  405.     m_ctrlSpinYear.EnableWindow(bEnable);
  406.     m_ctrlSpinDay.EnableWindow(bEnable);
  407.   #endif
  408. }
  409.  
  410.  
  411. void CCDateDlg::SetValue(const CDate& value)
  412. {
  413.   m_bInValid = !value.IsValid();
  414.   if (!m_bInValid)
  415.   {
  416.     m_nDay = value.GetDay();
  417.     m_nMonth = value.GetMonth();
  418.     m_lYear = value.GetYear();
  419.   }
  420. }
  421.  
  422.  
  423. CDate CCDateDlg::GetValue()
  424. {
  425.   CDate rVal;
  426.   if (!m_bInValid)
  427.   {
  428.     #ifdef _DEBUG
  429.     BOOL bOldDoAsserts = CDate::SetDoConstructorAsserts(FALSE);
  430.     #endif
  431.     rVal = CDate(m_lYear, (WORD) m_nMonth, (WORD) m_nDay);
  432.     #ifdef _DEBUG
  433.     CDate::SetDoConstructorAsserts(bOldDoAsserts);
  434.     #endif
  435.   }
  436.  
  437.   return rVal;
  438. }
  439.  
  440.  
  441. CCLTimeOfDayDlg::CCLTimeOfDayDlg()
  442. {
  443.   m_nHour = 0;
  444.   m_nMinute = 0;
  445.   m_nSecond = 0;
  446.   m_nMilliSecond = 0;
  447.   m_bInValid = FALSE;
  448. }
  449.  
  450.  
  451. CCLTimeOfDayDlg::CCLTimeOfDayDlg(CWnd* pParent, DWORD dwFlags)
  452.   : CDTDialog(IDD_CLTIMEOFDAY_WITHOUT_PIN, pParent)
  453. {
  454.   //DT_PUSHPIN & DT_CLOSEONDEACTIVE should be used with DT_MODELESS only
  455.   if (dwFlags & DT_PUSHPIN)
  456.     ASSERT(dwFlags & DT_MODELESS);
  457.   if (dwFlags & DT_CLOSEONDEACTIVE)
  458.     ASSERT(dwFlags & DT_MODELESS);
  459.  
  460.   //{{AFX_DATA_INIT(CCLTimeOfDayDlg)
  461.   m_nHour = 0;
  462.   m_nMinute = 0;
  463.   m_nSecond = 0;
  464.   m_nMilliSecond = 0;
  465.   m_bInValid = FALSE;
  466.   //}}AFX_DATA_INIT
  467.   m_dwFlags = dwFlags;
  468. }
  469.  
  470.  
  471. BOOL CCLTimeOfDayDlg::Create(CWnd* pParent, DWORD dwFlags)
  472. {
  473.   //should only be created modeless when DT_MODELESS flag is used
  474.   ASSERT(dwFlags & DT_MODELESS);
  475.  
  476.   m_pParentWnd = pParent;
  477.   m_dwFlags = dwFlags;
  478.  
  479.   UINT nIDTemplate = IDD_CLTIMEOFDAY_WITHOUT_PIN;
  480.   if (dwFlags & DT_PUSHPIN)
  481.     nIDTemplate = IDD_CLTIMEOFDAY;
  482.  
  483.   return CDTDialog::Create(nIDTemplate, pParent);
  484. }
  485.  
  486.  
  487. void CCLTimeOfDayDlg::DoDataExchange(CDataExchange* pDX)
  488. {
  489.   CDTDialog::DoDataExchange(pDX);
  490.   //{{AFX_DATA_MAP(CCLTimeOfDayDlg)
  491.   #ifdef _WIN32
  492.     DDX_Control(pDX, IDC_UPDOWN_HOUR, m_ctrlSpinHour);
  493.     DDX_Control(pDX, IDC_UPDOWN_MINUTE, m_ctrlSpinMinute);
  494.     DDX_Control(pDX, IDC_UPDOWN_SECOND, m_ctrlSpinSecond);
  495.     DDX_Control(pDX, IDC_UPDOWN_MILLISECOND, m_ctrlSpinMilliSecond);
  496.   #endif
  497.   DDX_Control(pDX, IDC_INVALID, m_ctrlInvalid);
  498.   DDX_Check(pDX, IDC_INVALID, m_bInValid);
  499.   //}}AFX_DATA_MAP
  500.  
  501.   if (!pDX->m_bSaveAndValidate || (pDX->m_bSaveAndValidate && !m_bInValid))
  502.   {
  503.     DDX_Text(pDX, IDC_HOUR, m_nHour);
  504.     DDV_MinMaxUInt(pDX, m_nHour, 0, 23);
  505.     DDX_Text(pDX, IDC_MINUTE, m_nMinute);
  506.     DDV_MinMaxUInt(pDX, m_nMinute, 0, 59);
  507.     DDX_Text(pDX, IDC_SECOND, m_nSecond);
  508.     DDV_MinMaxUInt(pDX, m_nSecond, 0, 59);
  509.     DDX_Text(pDX, IDC_MILLISECOND, m_nMilliSecond);
  510.     DDV_MinMaxUInt(pDX, m_nMilliSecond, 0, 999);  
  511.   }
  512.  
  513.   if (!pDX->m_bSaveAndValidate)
  514.     OnInvalid();
  515. }
  516.  
  517.  
  518. BOOL CCLTimeOfDayDlg::OnInitDialog() 
  519. {
  520.   BOOL rval = CDTDialog::OnInitDialog();
  521.   #ifdef _WIN32
  522.     m_ctrlSpinHour.SetRange(0, 23);
  523.     m_ctrlSpinMinute.SetRange(0, 59);
  524.     m_ctrlSpinSecond.SetRange(0, 59);
  525.     m_ctrlSpinMilliSecond.SetRange(0, 999);
  526.   #endif
  527.  
  528.   //disable the invalid check box if required
  529.   if (m_dwFlags & DT_ONLYVALID)
  530.     m_ctrlInvalid.EnableWindow(FALSE);
  531.  
  532.   //disable the millisecond edit if required
  533.   if (m_dwFlags & DT_NOMILLISECOND)
  534.   {
  535.     GetDlgItem(IDC_MILLISECOND)->EnableWindow(FALSE);
  536.     #ifdef _WIN32
  537.       m_ctrlSpinMilliSecond.EnableWindow(FALSE);
  538.     #endif  
  539.     GetDlgItem(IDC_MILLISECOND_PRMPT)->EnableWindow(FALSE);
  540.   }
  541.  
  542.   return rval;
  543. }
  544.  
  545.  
  546. void CCLTimeOfDayDlg::OnInvalid() 
  547. {
  548.   BOOL bEnable = !m_ctrlInvalid.GetCheck();
  549.   GetDlgItem(IDC_HOUR_PRMPT)->EnableWindow(bEnable);
  550.   GetDlgItem(IDC_MINUTE_PRMPT)->EnableWindow(bEnable);
  551.   GetDlgItem(IDC_SECOND_PRMPT)->EnableWindow(bEnable);
  552.   GetDlgItem(IDC_MILLISECOND_PRMPT)->EnableWindow(bEnable);
  553.   GetDlgItem(IDC_HOUR)->EnableWindow(bEnable);
  554.   GetDlgItem(IDC_MINUTE)->EnableWindow(bEnable);
  555.   GetDlgItem(IDC_SECOND)->EnableWindow(bEnable);
  556.   GetDlgItem(IDC_MILLISECOND)->EnableWindow(bEnable);
  557.   #ifdef _WIN32
  558.     m_ctrlSpinHour.EnableWindow(bEnable);
  559.     m_ctrlSpinMinute.EnableWindow(bEnable);
  560.     m_ctrlSpinSecond.EnableWindow(bEnable);
  561.     m_ctrlSpinMilliSecond.EnableWindow(bEnable);
  562.   #endif
  563. }
  564.  
  565.  
  566. void CCLTimeOfDayDlg::SetValue(const CLTimeOfDay& value)
  567. {
  568.   m_bInValid = !value.IsValid();
  569.   if (!m_bInValid)
  570.   {
  571.     m_nHour = value.GetHour();
  572.     m_nMinute = value.GetMinute();
  573.     m_nSecond = value.GetSecond();
  574.     m_nMilliSecond = value.GetMilliSecond();
  575.   }
  576. }
  577.  
  578.  
  579. CLTimeOfDay CCLTimeOfDayDlg::GetValue()
  580. {
  581.   CLTimeOfDay rVal;
  582.   if (!m_bInValid)
  583.   {
  584.     #ifdef _DEBUG
  585.     BOOL bOldDoAsserts = CLTimeOfDay::SetDoConstructorAsserts(FALSE);
  586.     #endif
  587.     rVal = CLTimeOfDay((WORD) m_nHour, (WORD) m_nMinute, (WORD) m_nSecond, (WORD) m_nMilliSecond);
  588.     #ifdef _DEBUG
  589.     CLTimeOfDay::SetDoConstructorAsserts(bOldDoAsserts);
  590.     #endif
  591.   }
  592.  
  593.   return rVal;
  594. }
  595.  
  596.  
  597. CCLTimeSpanDlg::CCLTimeSpanDlg()
  598. {
  599.   m_lDay = 0;
  600.   m_nHour = 0;
  601.   m_nMinute = 0;
  602.   m_nSecond = 0;
  603.   m_nMilliSecond = 0;
  604.   m_bInValid = FALSE;
  605. }
  606.  
  607.  
  608. CCLTimeSpanDlg::CCLTimeSpanDlg(CWnd* pParent, DWORD dwFlags)
  609.   : CDTDialog(IDD_CLTIMESPAN_WITHOUT_PIN, pParent)
  610. {
  611.   //DT_PUSHPIN & DT_CLOSEONDEACTIVE should be used with DT_MODELESS only
  612.   if (dwFlags & DT_PUSHPIN)
  613.     ASSERT(dwFlags & DT_MODELESS);
  614.   if (dwFlags & DT_CLOSEONDEACTIVE)
  615.     ASSERT(dwFlags & DT_MODELESS);
  616.  
  617.   //{{AFX_DATA_INIT(CCLTimeOfDayDlg)
  618.   m_lDay = 0;
  619.   m_nHour = 0;
  620.   m_nMinute = 0;
  621.   m_nSecond = 0;
  622.   m_nMilliSecond = 0;
  623.   m_bInValid = FALSE;
  624.   //}}AFX_DATA_INIT
  625.   m_dwFlags = dwFlags;
  626. }
  627.  
  628.  
  629. BOOL CCLTimeSpanDlg::Create(CWnd* pParent, DWORD dwFlags)
  630. {
  631.   //should only be created modeless when DT_MODELESS flag is used
  632.   ASSERT(dwFlags & DT_MODELESS);
  633.  
  634.   m_pParentWnd = pParent;
  635.   m_dwFlags = dwFlags;
  636.  
  637.   UINT nIDTemplate = IDD_CLTIMESPAN_WITHOUT_PIN;
  638.   if (dwFlags & DT_PUSHPIN)
  639.     nIDTemplate = IDD_CLTIMESPAN;
  640.  
  641.   return CDTDialog::Create(nIDTemplate, pParent);
  642. }
  643.  
  644.  
  645. void CCLTimeSpanDlg::DoDataExchange(CDataExchange* pDX)
  646. {
  647.   CDTDialog::DoDataExchange(pDX);
  648.   //{{AFX_DATA_MAP(CCLTimeSpanDlg)
  649.   #ifdef _WIN32
  650.     DDX_Control(pDX, IDC_UPDOWN_DAY3, m_ctrlSpinDay);
  651.     DDX_Control(pDX, IDC_UPDOWN_HOUR3, m_ctrlSpinHour);
  652.     DDX_Control(pDX, IDC_UPDOWN_MINUTE3, m_ctrlSpinMinute);
  653.     DDX_Control(pDX, IDC_UPDOWN_SECOND3, m_ctrlSpinSecond);
  654.     DDX_Control(pDX, IDC_UPDOWN_MILLISECOND3, m_ctrlSpinMilliSecond);
  655.   #endif
  656.   DDX_Control(pDX, IDC_INVALID, m_ctrlInvalid);
  657.   DDX_Check(pDX, IDC_INVALID, m_bInValid);
  658.   //}}AFX_DATA_MAP
  659.  
  660.   if (!pDX->m_bSaveAndValidate || (pDX->m_bSaveAndValidate && !m_bInValid))
  661.   {
  662.     DDX_Text(pDX, IDC_DAY, m_lDay);
  663.     DDX_Text(pDX, IDC_HOUR, m_nHour);
  664.     DDV_MinMaxUInt(pDX, m_nHour, 0, 23);
  665.     DDX_Text(pDX, IDC_MINUTE, m_nMinute);
  666.     DDV_MinMaxUInt(pDX, m_nMinute, 0, 59);
  667.     DDX_Text(pDX, IDC_SECOND, m_nSecond);
  668.     DDV_MinMaxUInt(pDX, m_nSecond, 0, 59);
  669.     DDX_Text(pDX, IDC_MILLISECOND, m_nMilliSecond);
  670.     DDV_MinMaxUInt(pDX, m_nMilliSecond, 0, 999);  
  671.   }
  672.   
  673.   if (!pDX->m_bSaveAndValidate)
  674.     OnInvalid();
  675. }
  676.  
  677.  
  678. BOOL CCLTimeSpanDlg::OnInitDialog() 
  679. {
  680.   BOOL rval = CDTDialog::OnInitDialog();
  681.   #ifdef _WIN32
  682.     m_ctrlSpinDay.SetRange(UD_MINVAL, UD_MAXVAL);
  683.     m_ctrlSpinHour.SetRange(0, 23);
  684.     m_ctrlSpinMinute.SetRange(0, 59);
  685.     m_ctrlSpinSecond.SetRange(0, 59);
  686.     m_ctrlSpinMilliSecond.SetRange(0, 999);
  687.   #endif
  688.  
  689.   //disable the invalid check box if required
  690.   if (m_dwFlags & DT_ONLYVALID)
  691.     m_ctrlInvalid.EnableWindow(FALSE);
  692.  
  693.   //disable the millisecond edit if required
  694.   if (m_dwFlags & DT_NOMILLISECOND)
  695.   {
  696.     GetDlgItem(IDC_MILLISECOND)->EnableWindow(FALSE);
  697.     #ifdef _WIN32
  698.       m_ctrlSpinMilliSecond.EnableWindow(FALSE);
  699.     #endif
  700.     GetDlgItem(IDC_MILLISECOND_PRMPT)->EnableWindow(FALSE);
  701.   }
  702.  
  703.   return rval;
  704. }
  705.  
  706.  
  707. void CCLTimeSpanDlg::OnInvalid() 
  708. {
  709.   BOOL bEnable = !m_ctrlInvalid.GetCheck();
  710.   GetDlgItem(IDC_DAY_PRMPT)->EnableWindow(bEnable);
  711.   GetDlgItem(IDC_HOUR_PRMPT)->EnableWindow(bEnable);
  712.   GetDlgItem(IDC_MINUTE_PRMPT)->EnableWindow(bEnable);
  713.   GetDlgItem(IDC_SECOND_PRMPT)->EnableWindow(bEnable);
  714.   GetDlgItem(IDC_MILLISECOND_PRMPT)->EnableWindow(bEnable);
  715.   GetDlgItem(IDC_DAY)->EnableWindow(bEnable);
  716.   GetDlgItem(IDC_HOUR)->EnableWindow(bEnable);
  717.   GetDlgItem(IDC_MINUTE)->EnableWindow(bEnable);
  718.   GetDlgItem(IDC_SECOND)->EnableWindow(bEnable);
  719.   GetDlgItem(IDC_MILLISECOND)->EnableWindow(bEnable);
  720.   #ifdef _WIN32
  721.     m_ctrlSpinDay.EnableWindow(bEnable);
  722.     m_ctrlSpinHour.EnableWindow(bEnable);
  723.     m_ctrlSpinMinute.EnableWindow(bEnable);
  724.     m_ctrlSpinSecond.EnableWindow(bEnable);
  725.     m_ctrlSpinMilliSecond.EnableWindow(bEnable);
  726.   #endif
  727. }
  728.  
  729.  
  730. void CCLTimeSpanDlg::SetValue(const CLTimeSpan& value)
  731. {
  732.   m_bInValid = !value.IsValid();
  733.   if (!m_bInValid)
  734.   {
  735.     m_lDay = value.GetTotalDays();
  736.     m_nHour = value.GetHours();
  737.     m_nMinute = value.GetMinutes();
  738.     m_nSecond = value.GetSeconds();
  739.     m_nMilliSecond = value.GetMilliSeconds();
  740.   }
  741. }
  742.  
  743.  
  744. CLTimeSpan CCLTimeSpanDlg::GetValue()
  745. {
  746.   CLTimeSpan rVal;
  747.   if (!m_bInValid)
  748.   {
  749.     #ifdef _DEBUG
  750.     BOOL bOldDoAsserts = CLTimeSpan::SetDoConstructorAsserts(FALSE);
  751.     #endif
  752.     rVal = CLTimeSpan(m_lDay, (WORD) m_nHour, (WORD) m_nMinute, (WORD) m_nSecond, (WORD) m_nMilliSecond);
  753.     #ifdef _DEBUG
  754.     CLTimeSpan::SetDoConstructorAsserts(bOldDoAsserts);
  755.     #endif
  756.   }
  757.  
  758.   return rVal;
  759. }
  760.  
  761.  
  762. CCLDateDlg::CCLDateDlg()
  763. {
  764.   m_nHour = 0;
  765.   m_nMinute = 0;
  766.   m_nSecond = 0;
  767.   m_nMilliSecond = 0;
  768.   m_bInValid = FALSE;
  769.   m_nDay = 1;
  770.   m_lYear = CDate::CurrentYear();
  771.   m_nMonth = 1;
  772.   m_nTimeFrame = 0;
  773. }
  774.  
  775.  
  776. CCLDateDlg::CCLDateDlg(CWnd* pParent, DWORD dwFlags)
  777.   : CDTDialog(IDD_CLDATE_WITHOUT_PIN, pParent)
  778. {
  779.   //DT_PUSHPIN & DT_CLOSEONDEACTIVE should be used with DT_MODELESS only
  780.   if (dwFlags & DT_PUSHPIN)
  781.     ASSERT(dwFlags & DT_MODELESS);
  782.   if (dwFlags & DT_CLOSEONDEACTIVE)
  783.     ASSERT(dwFlags & DT_MODELESS);
  784.  
  785.   //{{AFX_DATA_INIT(CCLDateDlg)
  786.   m_nHour = 0;
  787.   m_nMinute = 0;
  788.   m_nSecond = 0;
  789.   m_nMilliSecond = 0;
  790.   m_nDay = 0;
  791.   m_lYear = 0;
  792.   m_bInValid = FALSE;
  793.   //}}AFX_DATA_INIT
  794.   m_nDay = 1;
  795.   m_lYear = CDate::CurrentYear();
  796.   m_nMonth = 1;
  797.   m_nTimeFrame = 0;
  798.   m_dwFlags = dwFlags;
  799. }
  800.  
  801.  
  802. BOOL CCLDateDlg::Create(CWnd* pParent, DWORD dwFlags)
  803. {
  804.   //should only be created modeless when DT_MODELESS flag is used
  805.   ASSERT(dwFlags & DT_MODELESS);
  806.  
  807.   m_pParentWnd = pParent;
  808.   m_dwFlags = dwFlags;
  809.  
  810.   UINT nIDTemplate = IDD_CLDATE_WITHOUT_PIN;
  811.   if (dwFlags & DT_PUSHPIN)
  812.     nIDTemplate = IDD_CLDATE;
  813.  
  814.   return CDTDialog::Create(nIDTemplate, pParent);
  815. }
  816.  
  817.  
  818. void CCLDateDlg::DoDataExchange(CDataExchange* pDX)
  819. {
  820.   CDTDialog::DoDataExchange(pDX);
  821.   //{{AFX_DATA_MAP(CCLDateDlg)
  822.   DDX_Control(pDX, IDC_TIMEFRAME, m_ctrlTimeFrame);
  823.   #ifdef _WIN32
  824.     DDX_Control(pDX, IDC_UPDOWN_HOUR2, m_ctrlSpinHour);
  825.     DDX_Control(pDX, IDC_UPDOWN_MINUTE2, m_ctrlSpinMinute);
  826.     DDX_Control(pDX, IDC_UPDOWN_SECOND2, m_ctrlSpinSecond);
  827.     DDX_Control(pDX, IDC_UPDOWN_MILLISECOND2, m_ctrlSpinMilliSecond);
  828.     DDX_Control(pDX, IDC_UPDOWN_YEAR2, m_ctrlSpinYear);
  829.     DDX_Control(pDX, IDC_UPDOWN_DAY2, m_ctrlSpinDay);  
  830.   #endif
  831.   DDX_Control(pDX, IDC_INVALID, m_ctrlInvalid);
  832.   DDX_Control(pDX, IDC_MONTH, m_ctrlMonth);
  833.   DDX_Check(pDX, IDC_INVALID, m_bInValid);
  834.   //}}AFX_DATA_MAP
  835.  
  836.   if (!pDX->m_bSaveAndValidate || (pDX->m_bSaveAndValidate && !m_bInValid))
  837.   {
  838.     DDX_Text(pDX, IDC_HOUR, m_nHour);
  839.     DDV_MinMaxUInt(pDX, m_nHour, 0, 23);
  840.     DDX_Text(pDX, IDC_MINUTE, m_nMinute);
  841.     DDV_MinMaxUInt(pDX, m_nMinute, 0, 59);
  842.     DDX_Text(pDX, IDC_SECOND, m_nSecond);
  843.     DDV_MinMaxUInt(pDX, m_nSecond, 0, 59);
  844.     DDX_Text(pDX, IDC_MILLISECOND, m_nMilliSecond);
  845.     DDV_MinMaxUInt(pDX, m_nMilliSecond, 0, 999);  
  846.     DDX_Text(pDX, IDC_YEAR, m_lYear);
  847.     DDX_Text(pDX, IDC_DAY, m_nDay);
  848.   }
  849.  
  850.   if (pDX->m_bSaveAndValidate)
  851.   {
  852.     m_nMonth = m_ctrlMonth.GetCurSel() + 1;
  853.     m_nTimeFrame = m_ctrlTimeFrame.GetCurSel();
  854.   }
  855.   else
  856.   {
  857.     m_ctrlMonth.SetCurSel(m_nMonth-1);
  858.     m_ctrlTimeFrame.SetCurSel(m_nTimeFrame);
  859.     OnInvalid();
  860.   }
  861.  
  862.   DDV_MinMaxUInt(pDX, m_nDay, 1, (UINT) CDate::DaysInMonth((WORD) m_nMonth, CDate::IsLeap(m_lYear)));
  863. }
  864.  
  865.  
  866. BOOL CCLDateDlg::OnInitDialog() 
  867. {
  868.   //Add the month strings
  869.   CComboBox* pMonthCombo = (CComboBox*) GetDlgItem(IDC_MONTH);
  870.   for (WORD i=1; i<13; i++)
  871.     pMonthCombo->AddString(CDate::GetFullStringMonth(i));
  872.  
  873.   //Add the time frame strings (ordering is important)
  874.   CString sTimeFrame;
  875.   CComboBox* pTimeFrameCombo = (CComboBox*) GetDlgItem(IDC_TIMEFRAME);
  876.   if (!sTimeFrame.LoadString(IDS_UTC))
  877.     ASSERT(FALSE);
  878.   pTimeFrameCombo->AddString(sTimeFrame);
  879.  
  880.   if (!sTimeFrame.LoadString(IDS_ET))
  881.     ASSERT(FALSE);
  882.   pTimeFrameCombo->AddString(sTimeFrame);
  883.  
  884.   if (!sTimeFrame.LoadString(IDS_LOCAL))
  885.     ASSERT(FALSE);
  886.   pTimeFrameCombo->AddString(sTimeFrame);
  887.  
  888.   //Call up to the parent
  889.   BOOL rval = CDTDialog::OnInitDialog();
  890.  
  891.   #ifdef _WIN32
  892.     m_ctrlSpinHour.SetRange(0, 23);
  893.     m_ctrlSpinMinute.SetRange(0, 59);
  894.     m_ctrlSpinSecond.SetRange(0, 59);
  895.     m_ctrlSpinMilliSecond.SetRange(0, 999);
  896.     m_ctrlSpinYear.SetRange(UD_MINVAL, UD_MAXVAL);
  897.     m_ctrlSpinDay.SetRange(1, 31);
  898.   #endif
  899.  
  900.   //disable the invalid check box if required
  901.   if (m_dwFlags & DT_ONLYVALID)
  902.     m_ctrlInvalid.EnableWindow(FALSE);
  903.  
  904.   //disable the millisecond edit if required
  905.   if (m_dwFlags & DT_NOMILLISECOND)
  906.   {
  907.     GetDlgItem(IDC_MILLISECOND)->EnableWindow(FALSE);
  908.     #ifdef _WIN32
  909.       m_ctrlSpinMilliSecond.EnableWindow(FALSE);
  910.     #endif  
  911.     GetDlgItem(IDC_MILLISECOND_PRMPT)->EnableWindow(FALSE);
  912.   }
  913.  
  914.   return rval;
  915. }
  916.  
  917.  
  918. void CCLDateDlg::OnInvalid() 
  919. {
  920.   BOOL bEnable = !m_ctrlInvalid.GetCheck();
  921.   GetDlgItem(IDC_DAY_PRMPT)->EnableWindow(bEnable);
  922.   GetDlgItem(IDC_MONTH_PRMPT)->EnableWindow(bEnable);
  923.   GetDlgItem(IDC_YEAR_PRMPT)->EnableWindow(bEnable);
  924.   GetDlgItem(IDC_HOUR_PRMPT)->EnableWindow(bEnable);
  925.   GetDlgItem(IDC_MINUTE_PRMPT)->EnableWindow(bEnable);
  926.   GetDlgItem(IDC_SECOND_PRMPT)->EnableWindow(bEnable);
  927.   GetDlgItem(IDC_MILLISECOND_PRMPT)->EnableWindow(bEnable);
  928.   GetDlgItem(IDC_DAY)->EnableWindow(bEnable);
  929.   GetDlgItem(IDC_MONTH)->EnableWindow(bEnable);
  930.   GetDlgItem(IDC_YEAR)->EnableWindow(bEnable);
  931.   GetDlgItem(IDC_HOUR)->EnableWindow(bEnable);
  932.   GetDlgItem(IDC_MINUTE)->EnableWindow(bEnable);
  933.   GetDlgItem(IDC_SECOND)->EnableWindow(bEnable);
  934.   GetDlgItem(IDC_MILLISECOND)->EnableWindow(bEnable);
  935.   GetDlgItem(IDC_TIMEFRAME_PRMPT)->EnableWindow(bEnable);
  936.   m_ctrlMonth.EnableWindow(bEnable);
  937.   #ifdef _WIN32
  938.     m_ctrlSpinYear.EnableWindow(bEnable);
  939.     m_ctrlSpinDay.EnableWindow(bEnable);
  940.     m_ctrlSpinHour.EnableWindow(bEnable);
  941.     m_ctrlSpinMinute.EnableWindow(bEnable);
  942.     m_ctrlSpinSecond.EnableWindow(bEnable);
  943.     m_ctrlSpinMilliSecond.EnableWindow(bEnable);
  944.   #endif
  945.   m_ctrlTimeFrame.EnableWindow(bEnable);
  946. }
  947.  
  948.  
  949. void CCLDateDlg::SetValue(const CLDate& value)
  950. {
  951.   //should be optimised
  952.   m_bInValid = !value.IsValid();
  953.   if (!m_bInValid)
  954.   {
  955.     m_nDay = value.GetCDate().GetDay();
  956.     m_nMonth = value.GetCDate().GetMonth();
  957.     m_lYear = value.GetCDate().GetYear();
  958.     m_nHour = value.GetCLTimeOfDay().GetHour();
  959.     m_nMinute = value.GetCLTimeOfDay().GetMinute();
  960.     m_nSecond = value.GetCLTimeOfDay().GetSecond();
  961.     m_nMilliSecond = value.GetCLTimeOfDay().GetMilliSecond();
  962.     m_nTimeFrame = value.GetTimeFrame();
  963.   }
  964. }
  965.  
  966.  
  967. CLDate CCLDateDlg::GetValue()
  968. {
  969.   CLDate rVal;
  970.   if (!m_bInValid)
  971.   {
  972.     #ifdef _DEBUG
  973.     BOOL bOldDoAsserts = CLDate::SetDoConstructorAsserts(FALSE);
  974.     #endif
  975.     rVal = CLDate(m_lYear, (WORD) m_nMonth, (WORD) m_nDay, (WORD) m_nHour, (WORD) m_nMinute,
  976.                  (WORD) m_nSecond, (WORD) m_nMilliSecond, (TimeFrame) m_nTimeFrame);
  977.     #ifdef _DEBUG
  978.     CLDate::SetDoConstructorAsserts(bOldDoAsserts);
  979.     #endif
  980.   }
  981.  
  982.   return rVal;
  983. }
  984.  
  985.  
  986. CDateButton::CDateButton()
  987. {
  988.   m_pBuddy = NULL;
  989.   m_bFirstCall = TRUE;
  990. }
  991.  
  992.  
  993. CDateButton::~CDateButton()
  994. {
  995. }
  996.  
  997.  
  998. void CDateButton::SetBuddy(CWnd* pBuddy)
  999. {
  1000.   m_pBuddy = pBuddy;
  1001. }
  1002.  
  1003.  
  1004. BOOL CDateButton::PreTranslateMessage(MSG* pMsg) 
  1005. {                     
  1006.   #ifdef _WIN32
  1007.     //create the tooltip
  1008.     if (m_bFirstCall)
  1009.     {
  1010.       m_ToolTip.Create(this);
  1011.       m_ToolTip.Activate(TRUE);
  1012.       m_ToolTip.AddTool(this, IDS_TT_MODIFY);
  1013.       m_bFirstCall = FALSE;
  1014.     }
  1015.     
  1016.     //give the tooltip a chance to handle the message
  1017.     m_ToolTip.RelayEvent(pMsg);
  1018.   #endif
  1019.  
  1020.   return CButton::PreTranslateMessage(pMsg);
  1021. }
  1022.  
  1023.  
  1024. void CDateButton::OnClicked() 
  1025. {
  1026.   if (m_pBuddy)
  1027.     m_pBuddy->PostMessage(UWM_BN_CLICKED);
  1028.   else
  1029.     TRACE0("CDateButton: No auto buddy defined\n");
  1030. }                        
  1031.  
  1032.                      
  1033. LRESULT CDateButton::OnMyReflectedClicked(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1034. {   
  1035.   OnClicked();                                                    
  1036.   return 0;
  1037. }
  1038.  
  1039.  
  1040. LRESULT CDateButton::OnDlgClose(WPARAM wParam, LPARAM lParam) 
  1041. {
  1042.   LRESULT lresult = 0L;
  1043.  
  1044.   if (m_pBuddy)
  1045.     lresult = m_pBuddy->PostMessage(UWM_DLG_CLOSE, wParam, lParam);
  1046.   else
  1047.     TRACE0("CDateButton: No auto buddy defined\n");
  1048.  
  1049.   return lresult;
  1050. }
  1051.  
  1052.  
  1053. CDateTimeControl::CDateTimeControl()
  1054. {
  1055.   m_bSubclassed = FALSE;
  1056. }
  1057.  
  1058.  
  1059. CDateTimeControl::~CDateTimeControl()
  1060. {
  1061. }
  1062.  
  1063.  
  1064. BOOL CDateTimeControl::SubclassEdit(UINT iCtlID, CWnd* pParentWnd)
  1065. {
  1066.   //test our inputs
  1067.   ASSERT(this);
  1068.   if (!iCtlID || ! pParentWnd)
  1069.   {
  1070.     ASSERT(FALSE);
  1071.     TRACE0("CDateTimeControl::SubclassEdit -- Control iD or parent window class is invalid!\n");
  1072.     return FALSE;
  1073.   }                
  1074.   
  1075.   //this can only work if it's on a form view or dialog
  1076.   if (pParentWnd->IsKindOf(RUNTIME_CLASS(CFormView)) ||
  1077.      pParentWnd->IsKindOf(RUNTIME_CLASS(CDialog)))
  1078.   {
  1079.     //subclass the control
  1080.     if (SubclassDlgItem(iCtlID, pParentWnd))
  1081.     {
  1082.       m_bSubclassed = TRUE;
  1083.  
  1084.       //This control can only be used with a read only edit control
  1085.       LONG lStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
  1086.       if (!(lStyle & ES_READONLY))
  1087.       {
  1088.         TRACE0("CDateTimeControl::SubclassEdit -- ES_READONLY style should be set for the edit control\n");
  1089.         ASSERT(FALSE);
  1090.         return FALSE;
  1091.       }
  1092.  
  1093.       return AddEditButton();
  1094.     }
  1095.     else
  1096.     {
  1097.       TRACE0("CDateTimeControl::SubclassEdit -- Could not subclass edit control!\n");
  1098.       ASSERT(FALSE);
  1099.       return FALSE;
  1100.     }
  1101.   }
  1102.   else    //parent is not of CDialog or CFormView class
  1103.   {  
  1104.     TRACE0("CDateTimeControl::SubclassEdit -- Parent class is not a CFormView or CDialog!\n");
  1105.     return FALSE;
  1106.   }  
  1107. }
  1108.  
  1109.  
  1110. BOOL CDateTimeControl::SubclassEdit(HWND hEdit)
  1111. {   
  1112.   //test our inputs
  1113.   ASSERT(this);
  1114.   if (!IsWindow(hEdit))
  1115.   {
  1116.     ASSERT(FALSE);
  1117.     TRACE0("CDateTimeControl::SubclassEdit -- window handle is invalid!\n");
  1118.     return FALSE;
  1119.   }                
  1120.   
  1121.   //subclass the control
  1122.   if (SubclassWindow(hEdit))
  1123.   {
  1124.     m_bSubclassed = TRUE;
  1125.     
  1126.     //This control can only be used with a read only edit control
  1127.     LONG lStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
  1128.     if (!(lStyle & ES_READONLY))
  1129.     {
  1130.       TRACE0("CDateTimeControl::SubclassEdit -- ES_READONLY style should be set for the edit control\n");
  1131.       return FALSE;
  1132.     }
  1133.  
  1134.     return AddEditButton();
  1135.   }
  1136.   else
  1137.   {
  1138.     TRACE0("CDateTimeControl::SubclassEdit -- Could not subclass static control!\n");
  1139.     return FALSE;
  1140.   }
  1141. }
  1142.  
  1143.  
  1144. BOOL CDateTimeControl::AddEditButton()
  1145. {
  1146.   CRect Rect;
  1147.   GetWindowRect(Rect);
  1148.   GetParent()->ScreenToClient(Rect);
  1149.   Rect.left = Rect.right;
  1150.   Rect.right = Rect.left + (Rect.Height()*8/10);  //width is 8/10 of height
  1151.  
  1152.   //dynamically create the edit control
  1153.   CString sEditControlText;
  1154.   if (!sEditControlText.LoadString(IDS_EDIT_TEXT))
  1155.     ASSERT(FALSE);
  1156.   BOOL bSuccess = m_Edit.Create(sEditControlText, WS_VISIBLE | WS_CHILD | WS_GROUP, 
  1157.                                 Rect, GetParent(), DTIME_EDIT_CONTROL_ID);
  1158.  
  1159.   //tell the button to send click notifications to this window
  1160.   m_Edit.SetBuddy(this);
  1161.  
  1162.   //ensure it is using the same font as the parent
  1163.   m_Edit.SetFont(GetParent()->GetFont());
  1164.  
  1165.   return bSuccess;
  1166. }
  1167.  
  1168.  
  1169. CDateControl::CDateControl()
  1170. {
  1171.   m_pDlg = NULL;
  1172. }
  1173.  
  1174.  
  1175. CDateControl::~CDateControl()
  1176. {
  1177. }
  1178.  
  1179.  
  1180. LRESULT CDateControl::OnEditClick(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1181. {
  1182.   if (m_dwFlags & DT_MODELESS)
  1183.   {
  1184.     if (m_pDlg == NULL)
  1185.     {
  1186.       m_pDlg = new CCDateDlg;
  1187.       if (m_pDlg)
  1188.       {
  1189.         m_pDlg->SetValue(m_Value);
  1190.         m_pDlg->Create(&m_Edit, m_dwFlags); 
  1191.       }
  1192.     } 
  1193.     else
  1194.       TRACE0("Drop down dialog already visible\n");
  1195.   }
  1196.   else if (m_dwFlags & DT_MODAL)
  1197.   {
  1198.     CCDateDlg dlg(&m_Edit, m_dwFlags);
  1199.     dlg.SetValue(m_Value);
  1200.     if (dlg.DoModal() == IDOK)
  1201.     {
  1202.       CDate val = dlg.GetValue();
  1203.       SetWindowText(val.Format());
  1204.       m_Value = val;
  1205.     }
  1206.   }
  1207.   else
  1208.     ASSERT(FALSE);  //DT_MODELESS or DT_MODAL must be used
  1209.  
  1210.   return 0;
  1211. }
  1212.  
  1213.  
  1214. LRESULT CDateControl::OnDlgClose(WPARAM wParam, LPARAM /*lParam*/)
  1215. {
  1216.   if (wParam == 1)
  1217.   {
  1218.     CDate val = m_pDlg->GetValue();
  1219.     SetWindowText(val.Format());
  1220.     m_Value = val;
  1221.   }
  1222.  
  1223.   delete m_pDlg;
  1224.   m_pDlg = NULL;
  1225.  
  1226.   return 0;
  1227. }
  1228.  
  1229.  
  1230. void CDateControl::SetValue(const CDate& value)
  1231. {
  1232.   m_Value = value;
  1233.   SetWindowText(m_Value.Format());
  1234. }
  1235.  
  1236.  
  1237. CLTimeSpanControl::CLTimeSpanControl()
  1238. {
  1239.   m_pDlg = NULL;
  1240. }
  1241.  
  1242.  
  1243. CLTimeSpanControl::~CLTimeSpanControl()
  1244. {
  1245. }
  1246.  
  1247.  
  1248. LRESULT CLTimeSpanControl::OnEditClick(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1249. {
  1250.   if (m_dwFlags & DT_MODELESS)
  1251.   {
  1252.     if (m_pDlg == NULL)
  1253.     {
  1254.       m_pDlg = new CCLTimeSpanDlg;
  1255.       if (m_pDlg)
  1256.       {
  1257.         m_pDlg->SetValue(m_Value);
  1258.         m_pDlg->Create(&m_Edit, m_dwFlags); 
  1259.       }                          
  1260.       else
  1261.         TRACE0("Drop down dialog already visible\n");
  1262.     }
  1263.   }
  1264.   else if (m_dwFlags & DT_MODAL)
  1265.   {
  1266.     CCLTimeSpanDlg dlg(&m_Edit, m_dwFlags);
  1267.     dlg.SetValue(m_Value);
  1268.     if (dlg.DoModal() == IDOK)
  1269.     {
  1270.       CLTimeSpan val = dlg.GetValue();
  1271.       SetWindowText(val.Format());
  1272.       m_Value = val;
  1273.     }
  1274.   }
  1275.   else
  1276.     ASSERT(FALSE);  //DT_MODELESS or DT_MODAL must be used
  1277.  
  1278.   return 0;
  1279. }
  1280.  
  1281.  
  1282. LRESULT CLTimeSpanControl::OnDlgClose(WPARAM wParam, LPARAM /*lParam*/)
  1283. {
  1284.   if (wParam == 1)
  1285.   {
  1286.     CLTimeSpan val = m_pDlg->GetValue();
  1287.     SetWindowText(val.Format());
  1288.     m_Value = val;
  1289.   }
  1290.  
  1291.   delete m_pDlg;
  1292.   m_pDlg = NULL;
  1293.  
  1294.   return 0;
  1295. }
  1296.  
  1297.  
  1298. void CLTimeSpanControl::SetValue(const CLTimeSpan& value)
  1299. {
  1300.   m_Value = value;
  1301.   SetWindowText(m_Value.Format());
  1302. }
  1303.  
  1304.  
  1305. CLTimeOfDayControl::CLTimeOfDayControl()
  1306. {
  1307.   m_pDlg = NULL;
  1308. }
  1309.  
  1310.  
  1311. CLTimeOfDayControl::~CLTimeOfDayControl()
  1312. {
  1313. }
  1314.  
  1315.  
  1316. LRESULT CLTimeOfDayControl::OnEditClick(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1317. {
  1318.   if (m_dwFlags & DT_MODELESS)
  1319.   {
  1320.     if (m_pDlg == NULL)
  1321.     {
  1322.       m_pDlg = new CCLTimeOfDayDlg;
  1323.       if (m_pDlg)
  1324.       {
  1325.         m_pDlg->SetValue(m_Value);
  1326.         m_pDlg->Create(&m_Edit, m_dwFlags); 
  1327.       }                           
  1328.       else
  1329.         TRACE0("Drop down dialog already visible\n");
  1330.     }
  1331.   }
  1332.   else if (m_dwFlags & DT_MODAL)
  1333.   {
  1334.     CCLTimeOfDayDlg dlg(&m_Edit, m_dwFlags);
  1335.     dlg.SetValue(m_Value);
  1336.     if (dlg.DoModal() == IDOK)
  1337.     {
  1338.       CLTimeOfDay val = dlg.GetValue();
  1339.       SetWindowText(val.Format());
  1340.       m_Value = val;
  1341.     }
  1342.   }
  1343.   else
  1344.     ASSERT(FALSE);  //DT_MODELESS or DT_MODAL must be used
  1345.  
  1346.   return 0;
  1347. }
  1348.  
  1349.  
  1350. LRESULT CLTimeOfDayControl::OnDlgClose(WPARAM wParam, LPARAM /*lParam*/)
  1351. {
  1352.   if (wParam == 1)
  1353.   {
  1354.     CLTimeOfDay val = m_pDlg->GetValue();
  1355.     SetWindowText(val.Format());
  1356.     m_Value = val;
  1357.   }
  1358.  
  1359.   delete m_pDlg;
  1360.   m_pDlg = NULL;
  1361.  
  1362.   return 0;
  1363. }
  1364.  
  1365.  
  1366. void CLTimeOfDayControl::SetValue(const CLTimeOfDay& value)
  1367. {
  1368.   m_Value = value;
  1369.   SetWindowText(m_Value.Format());
  1370. }
  1371.  
  1372.  
  1373. CLDateControl::CLDateControl()
  1374. {
  1375.   m_pDlg = NULL;
  1376. }
  1377.  
  1378.  
  1379. CLDateControl::~CLDateControl()
  1380. {
  1381. }
  1382.  
  1383.  
  1384. LRESULT CLDateControl::OnEditClick(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1385. {
  1386.   if (m_dwFlags & DT_MODELESS)
  1387.   {
  1388.     if (m_pDlg == NULL)
  1389.     {
  1390.       m_pDlg = new CCLDateDlg;
  1391.       if (m_pDlg)
  1392.       {
  1393.         m_pDlg->SetValue(m_Value);
  1394.         m_pDlg->Create(&m_Edit, m_dwFlags); 
  1395.       }                      
  1396.       else
  1397.         TRACE0("Drop down dialog already visible\n");
  1398.     }
  1399.   }
  1400.   else if (m_dwFlags & DT_MODAL)
  1401.   {
  1402.     CCLDateDlg dlg(&m_Edit, m_dwFlags);
  1403.     dlg.SetValue(m_Value);
  1404.     if (dlg.DoModal() == IDOK)
  1405.     {
  1406.       CLDate val = dlg.GetValue();
  1407.       SetWindowText(val.Format());
  1408.       m_Value = val;
  1409.     }
  1410.   }
  1411.   else
  1412.     ASSERT(FALSE);  //DT_MODELESS or DT_MODAL must be used
  1413.  
  1414.  
  1415.   return 0;
  1416. }
  1417.  
  1418.  
  1419. LRESULT CLDateControl::OnDlgClose(WPARAM wParam, LPARAM /*lParam*/)
  1420. {
  1421.   if (wParam == 1)
  1422.   {
  1423.     CLDate val = m_pDlg->GetValue();
  1424.     SetWindowText(val.Format());
  1425.     m_Value = val;
  1426.   }
  1427.  
  1428.   delete m_pDlg;
  1429.   m_pDlg = NULL;
  1430.  
  1431.   return 0;
  1432. }
  1433.  
  1434.  
  1435. void CLDateControl::SetValue(const CLDate& value)
  1436. {
  1437.   m_Value = value;
  1438.   SetWindowText(m_Value.Format());
  1439. }
  1440.  
  1441.  
  1442. void DDX_CDateControl(CDataExchange* pDX, int nIDC, CDateControl& rCDateControl, DWORD dwFlags)
  1443.   HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  1444.   if (!pDX->m_bSaveAndValidate && rCDateControl.m_hWnd == NULL)    // not subclassed yet
  1445.   {
  1446.     if (!rCDateControl.SubclassEdit(hWndCtrl))
  1447.     {
  1448.       ASSERT(FALSE);      // possibly trying to subclass twice ?
  1449.       AfxThrowNotSupportedException();
  1450.     }
  1451.     else
  1452.       rCDateControl.SetFlags(dwFlags);
  1453.   }
  1454. }
  1455.  
  1456.  
  1457. void DDX_CLTimeSpanControl(CDataExchange* pDX, int nIDC, CLTimeSpanControl& rCLTimeSpanControl, DWORD dwFlags)
  1458. {
  1459.   HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  1460.   if (!pDX->m_bSaveAndValidate && rCLTimeSpanControl.m_hWnd == NULL)    // not subclassed yet
  1461.   {
  1462.     if (!rCLTimeSpanControl.SubclassEdit(hWndCtrl))
  1463.     {
  1464.       ASSERT(FALSE);      // possibly trying to subclass twice ?
  1465.       AfxThrowNotSupportedException();
  1466.     }
  1467.     else
  1468.       rCLTimeSpanControl.SetFlags(dwFlags);
  1469.   }
  1470. }
  1471.  
  1472.  
  1473. void DDX_CLTimeOfDayControl(CDataExchange* pDX, int nIDC, CLTimeOfDayControl& rCLTimeOfDayControl, DWORD dwFlags)
  1474. {
  1475.   HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  1476.   if (!pDX->m_bSaveAndValidate && rCLTimeOfDayControl.m_hWnd == NULL)    // not subclassed yet
  1477.   {
  1478.     if (!rCLTimeOfDayControl.SubclassEdit(hWndCtrl))
  1479.     {
  1480.       ASSERT(FALSE);      // possibly trying to subclass twice ?
  1481.       AfxThrowNotSupportedException();
  1482.     }
  1483.     else
  1484.       rCLTimeOfDayControl.SetFlags(dwFlags);
  1485.   }
  1486. }
  1487.  
  1488.  
  1489. void DDX_CLDateControl(CDataExchange* pDX, int nIDC, CLDateControl& rCLDateControl, DWORD dwFlags)
  1490. {
  1491.   HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  1492.   if (!pDX->m_bSaveAndValidate && rCLDateControl.m_hWnd == NULL)    // not subclassed yet
  1493.   {
  1494.     if (!rCLDateControl.SubclassEdit(hWndCtrl))
  1495.     {
  1496.       ASSERT(FALSE);      // possibly trying to subclass twice ?
  1497.       AfxThrowNotSupportedException();
  1498.     }
  1499.     else
  1500.       rCLDateControl.SetFlags(dwFlags);
  1501.   }
  1502. }
  1503.  
  1504.  
  1505. void DDX_CDate(CDataExchange* pDX, CDateControl& rCDateStatic, CDate& value)
  1506. {
  1507.   if (rCDateStatic.m_hWnd != NULL)
  1508.   {
  1509.     if (pDX->m_bSaveAndValidate)
  1510.     {
  1511.       rCDateStatic.GetValue(value);
  1512.     }
  1513.     else
  1514.     {
  1515.       rCDateStatic.SetValue(value);
  1516.     }
  1517.   }
  1518. }
  1519.  
  1520.  
  1521. void DDX_CLTimeSpan(CDataExchange* pDX, CLTimeSpanControl& rCLTimeSpanControl, CLTimeSpan& value)
  1522. {
  1523.   if (rCLTimeSpanControl.m_hWnd != NULL)
  1524.   {
  1525.     if (pDX->m_bSaveAndValidate)
  1526.     {
  1527.       rCLTimeSpanControl.GetValue(value);
  1528.     }
  1529.     else
  1530.     {
  1531.       rCLTimeSpanControl.SetValue(value);
  1532.     }
  1533.   }
  1534. }
  1535.  
  1536.  
  1537. void DDX_CLTimeOfDay(CDataExchange* pDX, CLTimeOfDayControl& rCLTimeOfDayControl, CLTimeOfDay& value)
  1538. {
  1539.   if (rCLTimeOfDayControl.m_hWnd != NULL)
  1540.   {
  1541.     if (pDX->m_bSaveAndValidate)
  1542.     {
  1543.       rCLTimeOfDayControl.GetValue(value);
  1544.     }
  1545.     else
  1546.     {
  1547.       rCLTimeOfDayControl.SetValue(value);
  1548.     }
  1549.   }
  1550. }
  1551.  
  1552.  
  1553. void DDX_CLDate(CDataExchange* pDX, CLDateControl& rCLDateControl, CLDate& value)
  1554. {
  1555.   if (rCLDateControl.m_hWnd != NULL)
  1556.   {
  1557.     if (pDX->m_bSaveAndValidate)
  1558.     {
  1559.       rCLDateControl.GetValue(value);
  1560.     }
  1561.     else
  1562.     {
  1563.       rCLDateControl.SetValue(value);
  1564.     }
  1565.   }
  1566. }
  1567.  
  1568.  
  1569. void DDV_MinMaxCDate(CDataExchange* pDX, CDate& value, CDate& minVal, CDate& maxVal)
  1570. {
  1571.   ASSERT(value.IsValid() && minVal.IsValid() && maxVal.IsValid());
  1572.   if (pDX->m_bSaveAndValidate && ((value < minVal) || (value > maxVal)))
  1573.   {
  1574.     AfxMessageBox(IDS_INVALID_DATE_RANGE, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_DATE_RANGE);
  1575.     pDX->Fail();
  1576.   }
  1577. }
  1578.  
  1579.  
  1580. void DDV_GreaterThanCDate(CDataExchange* pDX, CDate& value, CDate& minVal)
  1581. {
  1582.   ASSERT(value.IsValid() && minVal.IsValid());
  1583.   if (pDX->m_bSaveAndValidate && (value < minVal))
  1584.   {
  1585.     AfxMessageBox(IDS_INVALID_DATE_MIN, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_DATE_MIN);
  1586.     pDX->Fail();
  1587.   }
  1588. }
  1589.  
  1590.  
  1591. void DDV_LessThanCDate(CDataExchange* pDX, CDate& value, CDate& maxVal)
  1592. {
  1593.   ASSERT(value.IsValid() && maxVal.IsValid());
  1594.   if (pDX->m_bSaveAndValidate && (value > maxVal))
  1595.   {
  1596.     AfxMessageBox(IDS_INVALID_DATE_MAX, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_DATE_MAX);
  1597.     pDX->Fail();
  1598.   }
  1599. }
  1600.  
  1601.  
  1602. void DDV_MinMaxCLTimeSpan(CDataExchange* pDX, CLTimeSpan& value, CLTimeSpan& minVal, CLTimeSpan& maxVal)
  1603. {
  1604.   ASSERT(value.IsValid() && minVal.IsValid() && maxVal.IsValid());
  1605.   if (pDX->m_bSaveAndValidate && ((value < minVal) || (value > maxVal)))
  1606.   {
  1607.     AfxMessageBox(IDS_INVALID_TIMESPAN_RANGE, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMESPAN_RANGE);
  1608.     pDX->Fail();
  1609.   }
  1610. }
  1611.  
  1612.  
  1613. void DDV_GreaterThanCLTimeSpan(CDataExchange* pDX, CLTimeSpan& value, CLTimeSpan& minVal)
  1614. {
  1615.   ASSERT(value.IsValid() && minVal.IsValid());
  1616.   if (pDX->m_bSaveAndValidate && (value < minVal))
  1617.   {
  1618.     AfxMessageBox(IDS_INVALID_TIMESPAN_MIN, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMESPAN_MIN);
  1619.     pDX->Fail();
  1620.   }
  1621. }
  1622.  
  1623.  
  1624. void DDV_LessThanCLTimeSpan(CDataExchange* pDX, CLTimeSpan& value, CLTimeSpan& maxVal)
  1625. {
  1626.   ASSERT(value.IsValid() && maxVal.IsValid());
  1627.   if (pDX->m_bSaveAndValidate && (value > maxVal))
  1628.   {
  1629.     AfxMessageBox(IDS_INVALID_TIMESPAN_MAX, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMESPAN_MAX);
  1630.     pDX->Fail();
  1631.   }
  1632. }
  1633.  
  1634.  
  1635. void DDV_IsValidCLTimeSpan(CDataExchange* pDX, CLTimeSpan& value)
  1636. {
  1637.   if (pDX->m_bSaveAndValidate && (!value.IsValid()))
  1638.   {
  1639.     AfxMessageBox(IDS_INVALID_TIMESPAN, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMESPAN);
  1640.     pDX->Fail();
  1641.   }
  1642. }
  1643.  
  1644.  
  1645. void DDV_MinMaxCLTimeOfDay(CDataExchange* pDX, CLTimeOfDay& value, CLTimeOfDay& minVal, CLTimeOfDay& maxVal)
  1646. {
  1647.   ASSERT(value.IsValid() && minVal.IsValid() && maxVal.IsValid());
  1648.   if (pDX->m_bSaveAndValidate && ((value < minVal) || (value > maxVal)))
  1649.   {
  1650.     AfxMessageBox(IDS_INVALID_TIMEOFDAY_RANGE, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMEOFDAY_RANGE);
  1651.     pDX->Fail();
  1652.   }
  1653. }
  1654.  
  1655.  
  1656. void DDV_GreaterThanCLTimeOfDay(CDataExchange* pDX, CLTimeOfDay& value, CLTimeOfDay& minVal)
  1657. {
  1658.   ASSERT(value.IsValid() && minVal.IsValid());
  1659.   if (pDX->m_bSaveAndValidate && (value < minVal))
  1660.   {
  1661.     AfxMessageBox(IDS_INVALID_TIMEOFDAY_MIN, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMEOFDAY_MIN);
  1662.     pDX->Fail();
  1663.   }
  1664. }
  1665.  
  1666.  
  1667. void DDV_LessThanCLTimeOfDay(CDataExchange* pDX, CLTimeOfDay& value, CLTimeOfDay& maxVal)
  1668. {
  1669.   ASSERT(value.IsValid() && maxVal.IsValid());
  1670.   if (pDX->m_bSaveAndValidate && (value > maxVal))
  1671.   {
  1672.     AfxMessageBox(IDS_INVALID_TIMEOFDAY_MAX, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_TIMEOFDAY_MAX);
  1673.     pDX->Fail();
  1674.   }
  1675. }
  1676.  
  1677.  
  1678. void DDV_MinMaxCLDate(CDataExchange* pDX, CLDate& value, CLDate& minVal, CLDate& maxVal)
  1679. {
  1680.   ASSERT(value.IsValid() && minVal.IsValid() && maxVal.IsValid());
  1681.   if (pDX->m_bSaveAndValidate && ((value < minVal) || (value > maxVal)))
  1682.   {
  1683.     AfxMessageBox(IDS_INVALID_DATE_RANGE, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_DATE_RANGE);
  1684.     pDX->Fail();
  1685.   }
  1686. }
  1687.  
  1688.  
  1689. void DDV_GreaterThanCLDate(CDataExchange* pDX, CLDate& value, CLDate& minVal)
  1690. {
  1691.   ASSERT(value.IsValid() && minVal.IsValid());
  1692.   if (pDX->m_bSaveAndValidate && (value < minVal))
  1693.   {
  1694.     AfxMessageBox(IDS_INVALID_LDATE_MIN, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_LDATE_MIN);
  1695.     pDX->Fail();
  1696.   }
  1697. }
  1698.  
  1699.  
  1700. void DDV_LessThanCLDate(CDataExchange* pDX, CLDate& value, CLDate& maxVal)
  1701. {
  1702.   ASSERT(value.IsValid() && maxVal.IsValid());
  1703.   if (pDX->m_bSaveAndValidate && (value > maxVal))
  1704.   {
  1705.     AfxMessageBox(IDS_INVALID_LDATE_MAX, MB_OK | MB_ICONEXCLAMATION, DT_IDS_INVALID_LDATE_MAX);
  1706.     pDX->Fail();
  1707.   }
  1708. }
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.